home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
MACD 5
/
MACD 5.bin
/
workbench
/
libs
/
intuisup.lha
/
Intuisup
/
source.lha
/
Requester
/
requester.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-07-28
|
20KB
|
612 lines
/* $Revision Header *** Header built automatically - do not edit! ***********
*
* (C) Copyright 1991 by Torsten Jürgeleit
*
* Name .....: requester.c
* Created ..: Thursday 19-Dec-91 18:55:19
* Revision .: 5
*
* Date Author Comment
* ========= ==================== ====================
* 28-Jul-92 Torsten Jürgeleit different centering types for
* requesters
* 19-Jul-92 Torsten Jürgeleit remove/display_visible_gadget_lists()
* moved to gadgets1.c and instead of
* remove/display_visible_gadget_lists()
* now change_mouse_pointer(...,TRUE)
* 30-Apr-92 Torsten Jürgeleit now requester support rasters
* 01-Apr-92 Torsten Jürgeleit restore old mouse pointer position
* after displaying requester
* 28-Dec-91 Torsten Jürgeleit auto requester with body text string
* (with '\n' as new line indicator)
* instead of text array
* 19-Dec-91 Torsten Jürgeleit Created this file!
*
****************************************************************************
*
* Requester support routines
*
* $Revision Header ********************************************************/
/* Includes */
#include <exec/types.h>
#include <exec/memory.h>
#include <graphics/text.h>
#include <intuition/intuition.h>
#include <intuition/screens.h>
#ifdef AZTEC_C
#include <functions.h> /* needed for Aztec C - prototypes and pragmas for all Amiga system functions */
#endif
#include <libraries/memwatch.h> /* header file for memory debug link library (Fish 240) - AFTER functions.h */
#include <string.h>
#include <ctype.h>
#include "/render/render.h"
#include "/texts/texts.h"
#include "/borders/borders.h"
#include "/gadgets/gadgets.h"
#include "/gadgets/imports.h"
#include "/language/language.h"
#include "/pointer/pointer.h"
#include "requester.h"
/* Defines for auto request */
#define AUTO_REQ_DETAIL_PEN 0
#define AUTO_REQ_BLOCK_PEN 1
#define AUTO_REQ_IDCMP_FLAGS (GADGET_IDCMP_FLAGS_BUTTON | pos_idcmp_flags | neg_idcmp_flags)
#define AUTO_REQ_FLAGS (WINDOWDRAG | WINDOWDEPTH | SMART_REFRESH | NOCAREREFRESH | RMBTRAP | ACTIVATE)
#define AUTO_REQ_HORIZ_OFFSET 10
#define AUTO_REQ_VERT_OFFSET 5
#define AUTO_REQ_VERT_SPACING 2
#define AUTO_REQ_GADGET_HORIZ_BORDER_OFFSET 8
#define AUTO_REQ_GADGET_VERT_BORDER_OFFSET 4
#define AUTO_REQ_GADGET_HORIZ_SPACING 20
#define AUTO_REQ_GADGET_VERT_SPACING 10
/* Defines for requester */
#define REQ_DETAIL_PEN 0
#define REQ_BLOCK_PEN 1
#define REQ_IDCMP_FLAGS GADGET_IDCMP_FLAGS_ALL
#define REQ_FLAGS (SMART_REFRESH | NOCAREREFRESH | RMBTRAP | ACTIVATE)
/* Externals */
IMPORT struct IntuitionBase *IntuitionBase;
/* Display auto request */
BOOL
auto_request(struct Window *req_win, BYTE *title, BYTE *body_text,
BYTE *pos_text, BYTE *neg_text, LONG pos_idcmp_flags,
LONG neg_idcmp_flags, USHORT req_flags, BYTE **language_text_array)
{
BOOL result = FALSE;
if (body_text && (pos_text || neg_text)) {
struct RenderInfo *ri;
struct Screen *screen;
struct MinList list;
ULONG flags;
if (req_win) {
/* Remove gadgets and menu from given window */
change_mouse_pointer(req_win, NULL, TRUE);
}
/* Get render info */
screen = (req_win ? req_win->WScreen : NULL);
flags = RENDER_INFO_FLAG_INNER_WINDOW | (req_flags &
AUTO_REQ_FLAG_BACK_FILL ? RENDER_INFO_FLAG_BACK_FILL : 0);
if (ri = get_render_info(screen, (USHORT)flags)) {
BYTE *text;
LONG text_len;
/* Make copy of body text */
body_text = get_language_text(body_text, language_text_array);
text_len = strlen(body_text) + 2;
if (text = AllocMem(text_len, (LONG)MEMF_PUBLIC)) {
struct TextAttr *ta = &ri->ri_TextAttr;
struct GadgetData gadget_data[3], *gd = &gadget_data[0];
struct GadgetList *gl;
USHORT count, len1, len2, width1, width2, width, height,
gad_width, gad_height, num_gadgets, inner_width,
inner_height;
BYTE *ptr = text + 1, *line = text;
strcpy(ptr, body_text);
*(ptr + text_len - 2) = '\0';
/* Mark mark/count lines in body text string */
width1 = 0;
count = 1;
while ((ptr = strchr(ptr, '\\')) && toupper(*(ptr + 1)) == 'N') {
/* Save line length and mark end of line */
*line = ptr - (line + 1);
*ptr = '\0';
/* Calc max width of body text */
if ((len1 = print_text(ri, NULL, line + 1, 0, 0,
TEXT_DATA_TYPE_TEXT, TEXT_DATA_FLAG_NO_PRINT,
ta)) > width1) {
width1 = len1;
}
/* Increment pointers and line counter */
line = ptr + 1;
ptr += 2;
count++;
}
/* Prepare last line of body text */
*line = strlen(line + 1);
if ((len1 = print_text(ri, NULL, line + 1, 0, 0,
TEXT_DATA_TYPE_TEXT, TEXT_DATA_FLAG_NO_PRINT,
ta)) > width1) {
width1 = len1;
}
/* Calc max width of gadgets */
num_gadgets = 2;
if (!pos_text) {
len1 = 0;
num_gadgets = 1;
} else {
len1 = print_text(ri, NULL, get_language_text(pos_text,
language_text_array), 0, 0, TEXT_DATA_TYPE_TEXT,
TEXT_DATA_FLAG_NO_PRINT, ta);
}
if (!neg_text) {
len2 = 0;
num_gadgets = 1;
} else {
len2 = print_text(ri, NULL, get_language_text(neg_text,
language_text_array), 0, 0, TEXT_DATA_TYPE_TEXT,
TEXT_DATA_FLAG_NO_PRINT, ta);
}
gad_width = (len1 > len2 ? len1 : len2) +
2 * AUTO_REQ_GADGET_HORIZ_BORDER_OFFSET;
gad_height = ta->ta_YSize +
2 * AUTO_REQ_GADGET_VERT_BORDER_OFFSET;
width2 = num_gadgets * gad_width + (num_gadgets == 2 ?
AUTO_REQ_GADGET_HORIZ_SPACING : 0);
/* Calculate dimension of text area */
inner_width = (width1 > width2 ? width1 : width2);
inner_height = count * ta->ta_YSize + (count - 1) *
AUTO_REQ_VERT_SPACING;
/* Leave free space between raster and text */
if (req_flags & AUTO_REQ_FLAG_DRAW_RASTER) {
if (width1 > width2) {
inner_width += 2 * AUTO_REQ_HORIZ_OFFSET;
} else {
if ((width1 + 2 * AUTO_REQ_HORIZ_OFFSET) > width2) {
inner_width += (width1 + 2 * AUTO_REQ_HORIZ_OFFSET) -
width2;
}
}
inner_height += 2 * AUTO_REQ_VERT_OFFSET;
}
/* Calc width and height of requester window */
width = inner_width + 2 * AUTO_REQ_HORIZ_OFFSET;
height = inner_height + AUTO_REQ_GADGET_VERT_SPACING +
gad_height + AUTO_REQ_VERT_OFFSET;
/* Init gadget data and create gadget list */
flags = (req_flags & AUTO_REQ_FLAG_HOTKEY ?
GADGET_DATA_FLAG_HOTKEY : 0);
if (pos_text) {
gd->gd_Type = GADGET_DATA_TYPE_BUTTON;
gd->gd_Flags = flags |
(req_flags & AUTO_REQ_FLAG_MOVE_POINTER_POS ?
GADGET_DATA_FLAG_MOVE_POINTER : 0);
gd->gd_LeftEdge = (num_gadgets == 2 ? AUTO_REQ_HORIZ_OFFSET :
(width - gad_width) / 2);
gd->gd_TopEdge = height - (gad_height + AUTO_REQ_VERT_OFFSET);
gd->gd_Width = gad_width;
gd->gd_Height = gad_height;
gd->gd_Text = pos_text;
gd->gd_TextAttr = ta;
gd++;
}
if (neg_text) {
gd->gd_Type = GADGET_DATA_TYPE_BUTTON;
gd->gd_Flags = flags |
(req_flags & AUTO_REQ_FLAG_MOVE_POINTER_NEG ?
GADGET_DATA_FLAG_MOVE_POINTER : 0);
gd->gd_LeftEdge = (num_gadgets == 2 ? width - (gad_width +
AUTO_REQ_HORIZ_OFFSET) : (width - gad_width) / 2);
gd->gd_TopEdge = height - (gad_height + AUTO_REQ_VERT_OFFSET);
gd->gd_Width = gad_width;
gd->gd_Height = gad_height;
gd->gd_Text = neg_text;
gd->gd_TextAttr = ta;
gd++;
}
gd->gd_Type = INTUISUP_DATA_END;
if (gl = create_gadgets(ri, &gadget_data[0], 0, 0,
language_text_array)) {
struct NewWindow new_win, *nw = &new_win;
struct Window *win;
SHORT left_edge = 0, top_edge = 0;
/* Calc position of requester window */
if (req_flags & AUTO_REQ_FLAG_CENTER_MOUSE) {
struct Gadget *gad = gadget_address(gl, num_gadgets - 1);
/* Center last gadget of requester window over current position of mouse pointer */
left_edge = ri->ri_Screen->MouseX -
(gad->LeftEdge + gad->Width / 2);
top_edge = ri->ri_Screen->MouseY -
(gad->TopEdge + gad->Height / 2);
if (ri->ri_Flags & RENDER_INFO_FLAG_INNER_WINDOW) {
left_edge += ri->ri_WindowBorderLeft;
top_edge += ri->ri_WindowBorderTop;
}
/* Scale window position according to screen dimension */
if (left_edge < 0) {
left_edge = 0;
} else {
USHORT max_width = ri->ri_ScreenWidth;
if (left_edge > (max_width - width)) {
left_edge = max_width - width;
}
}
if (top_edge < 0) {
top_edge = 0;
} else {
USHORT max_height = ri->ri_ScreenHeight;
if (top_edge > (max_height - height)) {
top_edge = max_height - height;
}
}
}
/* Init and open requester window */
nw->LeftEdge = left_edge;
nw->TopEdge = top_edge;
nw->Width = width;
nw->Height = height;
nw->DetailPen = AUTO_REQ_DETAIL_PEN;
nw->BlockPen = AUTO_REQ_BLOCK_PEN;
nw->IDCMPFlags = AUTO_REQ_IDCMP_FLAGS;
nw->Flags = AUTO_REQ_FLAGS;
nw->FirstGadget = NULL;
nw->CheckMark = NULL;
nw->Title = (UBYTE *)(title ? get_language_text(title,
language_text_array) : " System Request ");
nw->Screen = screen;
nw->BitMap = NULL;
nw->MinWidth = 0;
nw->MinHeight = 0;
nw->MaxWidth = 0;
nw->MaxHeight = 0;
nw->Type = (screen ? screen->Flags & SCREENTYPE :
WBENCHSCREEN);
flags = (req_flags & AUTO_REQ_FLAG_RENDER_PENS ?
OPEN_WINDOW_FLAG_RENDER_PENS : 0);
if (win = open_window(ri, nw, (USHORT)flags)) {
struct MsgPort *up = win->UserPort;
struct Screen *front_screen;
SHORT mouse_x, mouse_y;
LONG ilock;
BOOL keepon = TRUE;
/* Save current mouse pointer position */
if (req_flags & AUTO_REQ_FLAG_MOVE_POINTER_POS ||
req_flags & AUTO_REQ_FLAG_MOVE_POINTER_NEG) {
mouse_x = win->MouseX;
mouse_y = win->MouseY;
}
/* Draw raster and border around text area */
if (req_flags & AUTO_REQ_FLAG_DRAW_RASTER) {
clear_window(ri, win, 0, 0, width, height,
CLEAR_WINDOW_FLAG_USE_RASTER);
clear_window(ri, win, AUTO_REQ_HORIZ_OFFSET,
AUTO_REQ_VERT_OFFSET, inner_width, inner_height, 0);
draw_border(ri, win, AUTO_REQ_HORIZ_OFFSET,
AUTO_REQ_VERT_OFFSET, inner_width, inner_height,
BORDER_DATA_TYPE_BOX1_IN);
/* Calc start position of text lines */
left_edge = 2 * AUTO_REQ_HORIZ_OFFSET;
top_edge = 2 * AUTO_REQ_VERT_OFFSET;
} else {
/* Calc start position of text lines */
left_edge = AUTO_REQ_HORIZ_OFFSET;
top_edge = AUTO_REQ_VERT_OFFSET;
}
/* Display texts and gadgets */
line = text;
flags = (req_flags & AUTO_REQ_FLAG_TEXT_CENTER ?
TEXT_DATA_FLAG_CENTER : 0) |
(req_flags & AUTO_REQ_FLAG_TEXT_COLOR2 ?
TEXT_DATA_FLAG_COLOR2 : 0);
while (count--) {
print_text(ri, win, line + 1, left_edge, top_edge,
TEXT_DATA_TYPE_TEXT, (USHORT)flags, ta);
line += *line + 2;
top_edge += ta->ta_YSize + AUTO_REQ_VERT_SPACING;
}
display_gadgets(win, gl);
/* Save current font scren and bring our screen to front */
ilock = LockIBase((LONG)NULL);
front_screen = IntuitionBase->FirstScreen;
UnlockIBase(ilock);
ScreenToFront(win->WScreen);
/* Beep if necessary */
if (req_flags & AUTO_REQ_FLAG_BEEP) {
DisplayBeep(NULL);
}
/* Wait for gadget or other IDCMP action */
do {
struct IntuiMessage *msg;
WaitPort(up);
while (msg = get_msg(up)) {
ULONG class = msg->Class;
if (class == ISUP_ID) {
if (pos_text && msg->Code == 0) {
result = TRUE;
}
keepon = FALSE;
} else {
if (pos_text && (class & pos_idcmp_flags)) {
result = TRUE;
keepon = FALSE;
} else {
if (neg_text && (class & neg_idcmp_flags)) {
keepon = FALSE;
}
}
}
reply_msg(msg);
}
} while (keepon == TRUE);
remove_gadgets(gl);
/* Before closing window restore old mouse pointer position */
if (req_flags & AUTO_REQ_FLAG_MOVE_POINTER_POS ||
req_flags & AUTO_REQ_FLAG_MOVE_POINTER_NEG) {
move_mouse_pointer(win, mouse_x, mouse_y, FALSE);
}
close_window(win, FALSE);
/* Bring old screen back to front */
ilock = LockIBase((LONG)NULL);
if (IntuitionBase->FirstScreen == front_screen) {
front_screen = NULL;
}
UnlockIBase(ilock);
if (front_screen) {
ScreenToFront(front_screen);
}
}
free_gadgets(gl);
}
FreeMem(text, text_len);
}
free_render_info(ri);
}
if (req_win) {
/* Enable gadgets and menu for given window */
restore_mouse_pointer(req_win);
}
}
return(result);
}
/* Display requester on given window */
struct RequesterList *
display_requester(struct Window *req_win, struct RequesterData *rd,
BYTE **language_text_array)
{
if (req_win && rd && rd->rd_Gadgets) {
struct RequesterList *rl;
USHORT rd_flags = rd->rd_Flags;
/* Alloc requester list and remove visible gadget list from window */
if (rl = AllocMem((LONG)sizeof(struct RequesterList),
(LONG)MEMF_PUBLIC | MEMF_CLEAR)) {
struct Screen *screen;
struct RenderInfo *ri;
USHORT flags;
/* Remove gadgets and menu from given window */
change_mouse_pointer(req_win, NULL, TRUE);
/* Get render info */
screen = req_win->WScreen;
flags = (rd_flags & REQ_DATA_FLAG_INNER_WINDOW ?
RENDER_INFO_FLAG_INNER_WINDOW : 0) |
(rd_flags & REQ_DATA_FLAG_BACK_FILL ?
RENDER_INFO_FLAG_BACK_FILL : 0) |
(rd_flags & REQ_DATA_FLAG_AVAIL_FONTS ?
RENDER_INFO_FLAG_AVAIL_FONTS : 0);
if (ri = get_render_info(screen, flags)) {
struct GadgetData *gd = rd->rd_Gadgets;
struct GadgetList *gl;
/* Init gadgets */
if (gl = create_gadgets(ri, gd, 0, 0, language_text_array)) {
struct NewWindow new_win, *nw = &new_win;
struct Window *win;
SHORT left_edge = 0, top_edge = 0;
/* Calc position of requester window */
if ((rd_flags & REQ_DATA_FLAG_CENTER_WINDOW) ||
(rd_flags & REQ_DATA_FLAG_CENTER_MOUSE)) {
USHORT width = rd->rd_Width, height = rd->rd_Height;
if (rd_flags & REQ_DATA_FLAG_CENTER_WINDOW) {
/* Center requester window on given window */
left_edge = req_win->LeftEdge +
(req_win->Width - width) / 2;
top_edge = req_win->TopEdge +
(req_win->Height - height) / 2;
} else {
/* Center last gadget of requester window over current position of mouse pointer */
left_edge = ri->ri_Screen->MouseX - width / 2;
top_edge = ri->ri_Screen->MouseY - height / 2;
}
if (ri->ri_Flags & RENDER_INFO_FLAG_INNER_WINDOW) {
left_edge += ri->ri_WindowBorderLeft;
top_edge += ri->ri_WindowBorderTop;
}
/* Scale window position according to screen dimension */
if (left_edge < 0) {
left_edge = 0;
} else {
USHORT max_width = ri->ri_ScreenWidth;
if (left_edge > (max_width - width)) {
left_edge = max_width - width;
}
}
if (top_edge < 0) {
top_edge = 0;
} else {
USHORT max_height = ri->ri_ScreenHeight;
if (top_edge > (max_height - height)) {
top_edge = max_height - height;
}
}
}
/* Save requester list ptr */
gl->gl_RequesterList = rl;
/* Init and open requester window */
nw->LeftEdge = left_edge;
nw->TopEdge = top_edge;
nw->Width = rd->rd_Width;
nw->Height = rd->rd_Height;
nw->DetailPen = REQ_DETAIL_PEN;
nw->BlockPen = REQ_BLOCK_PEN;
nw->IDCMPFlags = NULL; /* shared user port !!! */
nw->Flags = REQ_FLAGS |
(rd_flags & REQ_DATA_FLAG_DRAG_GADGET ? WINDOWDRAG : 0) |
(rd_flags & REQ_DATA_FLAG_DEPTH_GADGET ? WINDOWDEPTH : 0);
nw->FirstGadget = NULL;
nw->CheckMark = NULL;
nw->Title = (UBYTE *)(rd->rd_Title ?
get_language_text(rd->rd_Title, language_text_array) :
" Requester ");
nw->Screen = screen;
nw->BitMap = NULL;
nw->MinWidth = 0;
nw->MinHeight = 0;
nw->MaxWidth = 0;
nw->MaxHeight = 0;
nw->Type = (screen ? screen->Flags & SCREENTYPE :
WBENCHSCREEN);
flags = (rd_flags & REQ_DATA_FLAG_RENDER_PENS ?
OPEN_WINDOW_FLAG_RENDER_PENS : 0) |
(rd_flags & REQ_DATA_FLAG_CENTER_SCREEN ?
OPEN_WINDOW_FLAG_CENTER_SCREEN : 0);
if (win = open_window(ri, nw, flags)) {
struct BorderData *bd = rd->rd_Borders;
/* Enable shared user port */
win->UserPort = req_win->UserPort;
ModifyIDCMP(win, REQ_IDCMP_FLAGS);
/* Init requester list */
rl->rl_ID = ISUP_ID;
rl->rl_Flags = 0;
rl->rl_RenderInfo = ri;
rl->rl_Window = req_win;
rl->rl_ReqWindow = win;
rl->rl_GadgetList = gl;
/* Save current mouse pointer position if necessay */
for ( ; gd->gd_Type != INTUISUP_DATA_END; gd++) {
if (gd->gd_Flags & GADGET_DATA_FLAG_MOVE_POINTER) {
rl->rl_Flags |= REQ_FLAG_RESTORE_POINTER_POS;
rl->rl_MouseX = win->MouseX;
rl->rl_MouseY = win->MouseY;
break;
}
}
/* Draw raster from first border */
if ((rd_flags & REQ_DATA_FLAG_DRAW_RASTER) &&
bd && bd->bd_Type >= 1 &&
bd->bd_Type <= MAX_BORDER_DATA_TYPE) {
SHORT left_edge = bd->bd_LeftEdge,
top_edge = bd->bd_TopEdge, width = bd->bd_Width,
height = bd->bd_Height;
/* Draw raster and border */
clear_window(ri, win, 0, 0, rd->rd_Width,
rd->rd_Height, CLEAR_WINDOW_FLAG_USE_RASTER);
clear_window(ri, win, left_edge, top_edge, width,
height, 0);
draw_border(ri, win, left_edge, top_edge, width,
height, BORDER_DATA_TYPE_BOX1_IN);
/* Don't draw this border later */
bd++;
}
/* Display texts, borders and gadgets */
display_texts(ri, win, rd->rd_Texts, 0, 0,
language_text_array);
display_borders(ri, win, bd, 0, 0);
display_gadgets(win, gl);
return(rl);
}
free_gadgets(gl);
}
free_render_info(ri);
}
/* Enable gadgets and menu for given window */
restore_mouse_pointer(rl->rl_Window);
FreeMem(rl, (LONG)sizeof(struct RequesterList));
}
}
return(NULL);
}
/* Remove given requester */
VOID
remove_requester(struct RequesterList *rl)
{
if (rl && rl->rl_ID == ISUP_ID) {
remove_gadgets(rl->rl_GadgetList);
/* Before closing window restore old mouse pointer position */
if (rl->rl_Flags & REQ_FLAG_RESTORE_POINTER_POS) {
move_mouse_pointer(rl->rl_ReqWindow, rl->rl_MouseX, rl->rl_MouseY,
FALSE);
}
close_window(rl->rl_ReqWindow, TRUE); /* shared user port !!! */
/* Free resources */
free_gadgets(rl->rl_GadgetList);
free_render_info(rl->rl_RenderInfo);
/* Enable gadgets and menu for given window */
restore_mouse_pointer(rl->rl_Window);
FreeMem(rl, (LONG)sizeof(struct RequesterList));
}
}